package com.dhcc.sds.standard.service.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.dhcc.core.framework.result.node.ZTreeNode;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.sds.standard.dao.SdsStandSourceFieldMapper;
import com.dhcc.sds.standard.dao.SdsStandSourceMapper;
import com.dhcc.sds.standard.dto.TreeNode;
import com.dhcc.sds.standard.entity.*;
import com.dhcc.sds.standard.service.ISdsStandDicMatchService;
import com.dhcc.sds.standard.service.ISdsStandSourceService;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.plugins.Page;
import com.dhcc.core.framework.base.service.impl.BaseServiceImpl;
import com.dhcc.sds.standard.dao.SdsStandDicMapper;
import com.dhcc.sds.standard.service.ISdsStandDicService;

/**
 * 项目标准化字典表数据服务层接口
 * 
 * @ClassName: SdsStandDicServiceImpl
 * @Description: TODO
 * @author sunyingjie
 * @date 2021-03-22 10:09:57
 */
@Service("sdsStandDicService")
public class SdsStandDicServiceImpl extends BaseServiceImpl<SdsStandDicMapper, SdsStandDicEntity> implements ISdsStandDicService {

	@Autowired
	private SdsStandSourceMapper sourceMapper;

	@Autowired
	private SdsStandSourceFieldMapper sourceFieldMapper;

	@Autowired
	private SdsStandDicMapper standDicMapper;

	@Autowired
	private ISdsStandSourceService standSourceService;
	@Autowired
	private ISdsStandDicMatchService sdsStandDicMatchService;

	@Override
	public List<SdsStandDicEntity> page(Page<SdsStandDicEntity> page, Map<String, Object> map) {
		List<SdsStandDicEntity> page1 = this.baseMapper.page(page, map);
		return page1;
	}
	@Override
	public List<SdsStandDicEntity> list(Map<String, Object> map) {
		return this.baseMapper.list(map);
	}

	@Override
	public JSONArray getDicDescMap() {
		List<SdsStandDicEntity> list = standDicMapper.selectList(null);
		JSONArray entityArry = new JSONArray();
		for (SdsStandDicEntity standDicEntity : list) {
			JSONObject officeObj = new JSONObject();
			String value = String.valueOf(standDicEntity.getId());
			officeObj.put("value",value);
			officeObj.put("text",standDicEntity.getName());
//            dataMap.put(String.valueOf(sdsStandSourceEntity.getId()), sdsStandSourceEntity.getSourceDesc());
			entityArry.add(officeObj);
		}
		return entityArry;
	}

	@Override
	public JSONObject getDicMap() {
		List<SdsStandDicEntity> sdsStandDicEntities = standDicMapper.selectList(null);
		JSONObject dicMap = new JSONObject();
		dicMap.put("", "");
		for(SdsStandDicEntity standDicEntity : sdsStandDicEntities){
			dicMap.put(String.valueOf(standDicEntity.getId()), standDicEntity.getName());
		}
		return dicMap;
	}

	@Override
	public List<ZTreeNode> getCategoryTree() {
		List<ZTreeNode> tree = standDicMapper.tree();
		tree.add(ZTreeNode.createRoot());
		return tree;
	}

	@Override
	public List<SdsStandDicEntity> listBySource(String source) {

		SdsStandSourceEntity sourceByDesc = standSourceService.getSourceByDesc(source);

		List<SdsStandDicEntity> standDicEntitys = null;

		if(CommonUtil.isNotEmpty(sourceByDesc)){
			 standDicEntitys = standDicMapper.selectList(
					new EntityWrapper<SdsStandDicEntity>()
							.eq("source_id", sourceByDesc.getId())
			);
		}

		return standDicEntitys;
	}

	@Override
	public JSONObject getDicMapBySource(String source) {
		List<SdsStandDicEntity> sdsStandDicEntities = this.listBySource(source);
		JSONObject dicMap = new JSONObject();
		dicMap.put("", "");
		for(SdsStandDicEntity standDicEntity : sdsStandDicEntities){
			dicMap.put(String.valueOf(standDicEntity.getId()), standDicEntity.getName());
		}

		return dicMap;
	}

	@Override
	public SdsStandDicEntity getBySourceAndDicDesc(String sourceDesc, String dicDesc) {
		SdsStandSourceEntity sourceByDesc = standSourceService.getSourceByDesc(sourceDesc);
		SdsStandDicEntity standDicEntity = this.baseMapper.selectBySourceAndDicDesc(sourceByDesc.getId(), dicDesc);
		if (CommonUtil.isEmpty(standDicEntity)){
			SdsStandDicEntity standDicEntity1 = new SdsStandDicEntity();
			standDicEntity1.setParentId(sourceByDesc.getId());
			standDicEntity1.setName(dicDesc);
			this.baseMapper.insert(standDicEntity1);
			return standDicEntity1;
		}else {
			return standDicEntity;
		}
	}

	@Override
	public List<ZTreeNode> tree() {
		List<ZTreeNode> tree = this.baseMapper.tree();
		return tree;
	}

	@Override
	public List<TreeNode> getDicTree(Long parentId, Long dataSourceId) {
		List<TreeNode> treeList = new ArrayList<TreeNode>();
		List<TreeNode> treeParent = new ArrayList<TreeNode>();
		if (null == dataSourceId){
			if (0l == parentId || null == parentId || "".equals(parentId)){
				//treeParent = single2Tree(this.baseMapper.selectLevel());
				treeParent =this.baseMapper.selectLevel();
			}else {
				//treeParent = single2Tree(this.baseMapper.selectSecondary(parentId));
				treeParent = this.baseMapper.selectSecondary(parentId);
			}
		}else {
			//treeParent = single2Tree(this.baseMapper.selectByDataSourceId(dataSourceId));
			treeParent = this.baseMapper.selectByDataSourceId(dataSourceId);
		}

		if (treeParent != null && !treeParent.isEmpty()) {
			for (TreeNode treeNode : treeParent) {
				//List<TreeNode> chileTree = single2Tree(this.baseMapper.selectSecondary(treeNode.getId()));
				List<TreeNode> chileTree = this.baseMapper.selectSecondary(treeNode.getId());
				//数据库中没有最后一层级的标志，这里根据的是：如果根据当前的id查不到子级，那么他就是最后一级
				if (null != chileTree && !chileTree.isEmpty()) {
					//如果不是最后一级，继续调用getZUITree（）方法，并将查询到的值赋值给其父级的child属性
					treeNode.setChildren(getDicTree(treeNode.getId(), null));
				}
				treeList.add(treeNode);
			}
		}
		return treeList;
	}

	@Override
	public List<Tree<Long>> getDicTree2(Long dataSourceId) {
		List<SdsStandDicEntity> res = new ArrayList<>();
		List<SdsStandDicEntity> all = this.baseMapper.selectList(null);

		TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
		treeNodeConfig.setIdKey("id");
		treeNodeConfig.setParentIdKey("parentId");

		if (0l == dataSourceId){
			//构建树形
			List<Tree<Long>> trees = TreeUtil.build(all, 0L, treeNodeConfig, ((object, treeNode) -> {
				treeNode.setId(object.getId());//id
				treeNode.setParentId(object.getParentId());//父id
				treeNode.putExtra("text", object.getName());
				if (isLastNode(object, all)) {
					// 如果是最后一个节点，则不添加state属性
				} else {
					treeNode.putExtra("state", "closed"); //默认全部折叠
				}
			}));
			return trees;
		}else {
			List<SdsStandDicEntity> dicEntities = this.getStandDicListBySourceId(dataSourceId);
			for (SdsStandDicEntity dicEntity : dicEntities){
				getParentNode(res, all, dicEntity.getId());
			}
			res.addAll(dicEntities);
			//构建树形
			List<Tree<Long>> trees = TreeUtil.build(res, 0L, treeNodeConfig, ((object, treeNode) -> {
				treeNode.setId(object.getId());//id
				treeNode.setParentId(object.getParentId());//父id
				treeNode.putExtra("text", object.getName());
				if (isLastNode(object, dicEntities)) {
					// 如果是最后一个节点，则不添加state属性
				} else {
					treeNode.putExtra("state", "closed"); //默认全部折叠
				}
			}));
			return trees;
		}

	}

	private boolean isLastNode(SdsStandDicEntity currentNode, List<SdsStandDicEntity> allNodes) {
		for (SdsStandDicEntity node : allNodes) {
			if (node.getParentId().equals(currentNode.getId())) {
				return false; // 存在子节点，当前节点不是最底层节点
			}
		}
		return true; // 没有子节点，当前节点是最底层节点
	}

	private List<SdsStandDicEntity> getStandDicListBySourceId(Long dataSourceId) {
		List<SdsStandDicEntity> res = standDicMapper.selectDicByDataSourceId(dataSourceId);
		if (CommonUtil.isEmpty(res)) {
			//如果为空，则查询父级关联的标准字典
			SdsStandSourceEntity sourceEntity = standSourceService.selectById(dataSourceId);
			if (sourceEntity != null) {
				res = getStandDicListBySourceId(sourceEntity.getParentId());
			}
		}
		return res;
	}

	@Override
	public JSONArray getDicRoot() {
		List<SdsStandDicEntity> list = standDicMapper.selectDicRoot();
		JSONArray entityArry = new JSONArray();
		JSONObject obj = new JSONObject();
		obj.put("value", "");
		obj.put("text","全部");
		entityArry.add(obj);
		for (SdsStandDicEntity standDicEntity : list) {
			JSONObject officeObj = new JSONObject();
			officeObj.put("value",standDicEntity.getId());
			officeObj.put("text",standDicEntity.getName());
			entityArry.add(officeObj);
		}
		return entityArry;
	}

	@Override
	public boolean isHaveChildren(Long sdsStandDicId) {
		List<SdsStandDicEntity> dicEntities = this.baseMapper.selectList(new EntityWrapper<SdsStandDicEntity>()
				.eq("parent_id", sdsStandDicId));
		if (dicEntities.size() > 0){
			return true;
		}else {
			return false;
		}
	}

	@Override
	public void deleteAllById(Long sdsStandDicId) {
		ArrayList<Long> ids = new ArrayList<>();
		//先把要删除的一级分类id放入到集合中
		ids.add(sdsStandDicId);
		//递归的将一级分类下的id也加入到集合中
		this.getAllIds(ids, sdsStandDicId);
		//批量删除集合中的id
		this.baseMapper.deleteBatchIds(ids);
	}

	@Override
	public List<Long> getRootChildren(Long parentId) {
		List<Long> res = new ArrayList<>();
		List<SdsStandDicEntity> dicEntities = this.baseMapper.selectList(null);
		List<SdsStandDicEntity> collect = dicEntities.stream()
				.filter(l -> l.getParentId().equals(parentId))
				.peek(c -> c.setChildren(getChildren(dicEntities, c.getId())))
				.sorted(Comparator.comparingLong(SdsStandDicEntity::getId))
				.collect(Collectors.toList());
		for (SdsStandDicEntity standDicEntity : collect){
			if (null != standDicEntity.getChildren() && standDicEntity.getChildren().size() > 0){
				List<SdsStandDicEntity> dicEntities1 = standDicEntity.getChildren();
				getRootChildren(res, dicEntities1);
			}else {
				res.add(standDicEntity.getId());
			}
		}
		return res;
	}

	private void getAllIds(ArrayList<Long> ids, Long sdsStandDicId){
		List<SdsStandDicEntity> dicEntities = this.baseMapper.selectList(new EntityWrapper<SdsStandDicEntity>()
				.eq("parent_id", sdsStandDicId));
		for (SdsStandDicEntity standDicEntity : dicEntities){
			Long id = standDicEntity.getId();
			ids.add(id);
			this.getAllIds(ids,id);
		}
	}

	private List<TreeNode> single2Tree(List<TreeNode> lists) {
		List<TreeNode> treeList = new ArrayList<TreeNode>();
		if (!(lists == null) && !lists.isEmpty()) {
			for (TreeNode treeNode : lists) {
				TreeNode tempTree = new TreeNode();

				tempTree.setId(treeNode.getId());
				tempTree.setText(treeNode.getText());

				treeList.add(tempTree);
			}
		}

		return treeList;
	}

	private static void getParentNode(List<SdsStandDicEntity> childDic, List<SdsStandDicEntity> allList, Long pid) {
		allList.stream()
				//过滤出父id等于参数的id
				.filter(dic -> dic.getParentId().equals(pid))
				.forEach(dic -> {
					//递归遍历下一级
					getParentNode(childDic, allList, dic.getId());
					//添加
					childDic.add(dic);
				});
	}

	private List<SdsStandDicEntity> getChildren(List<SdsStandDicEntity> dicEntities, Long parentId) {
		return dicEntities.stream()
				.filter(l -> l.getParentId().equals(parentId))
				.peek(c -> c.setChildren(getChildren(dicEntities, c.getId())))
				.sorted(Comparator.comparingLong(SdsStandDicEntity::getId))
				.collect(Collectors.toList());

	}

	private List<Long> getRootChildren(List<Long> res, List<SdsStandDicEntity> dicEntities) {
		for (SdsStandDicEntity standDicEntity : dicEntities){
			if (null != standDicEntity.getChildren() && standDicEntity.getChildren().size() > 0){
				getRootChildren(res, standDicEntity.getChildren());
			}else {
				res.add(standDicEntity.getId());
			}
		}
		return res;
	}

}